package main

import (
	"flag"
	"fmt"
	"sync"
	"time"
)

var totalCount int
var paralleSize int
var reqConfPath string
var service = "lbs"
var funcID = -1
var totalTime int64

func main() {
	flag.IntVar(&totalCount, "totalCount", 10, "总的请求数")
	flag.IntVar(&paralleSize, "paralleSize", 5, "并发数")
	flag.StringVar(&reqConfPath, "reqConfPath", "", "请求req配置 json 格式")
	flag.Int64Var(&totalTime, "totalTime", 10, "压测时间")
	flag.StringVar(&service, "service", "lbs", "目标服务名")
	flag.IntVar(&funcID, "funcID", -1, "请求接口ID ")
	flag.Parse()
	xecuteTim := time.Duration(totalTime) * time.Second
	endTime := time.Now().Add(xecuteTim)
	wg := sync.WaitGroup{}
	wg.Add(paralleSize)
	tr := make([]*RPCStressTest, paralleSize)
	for i := 0; i < paralleSize; i++ {
		go func(cur int) {
			tster, err := GetDoTester(service, FuncID(funcID))
			tr[cur] = new(RPCStressTest)
			tr[cur].GoRoutineCount = paralleSize
			go func(idx int) {
				_rst := tr[idx]
				//日志监控
				for true {
					fmt.Printf("\n线程【%v】 当前成功数 %v, 当前失败数 %v\n", idx, _rst.successVisitTotal, _rst.errorVisitTotal)
					//fmt.Printf("压测进度: %v%", float64(index+1)/float64(totalCount)*100)
					time.Sleep(3 * time.Second)
				}
			}(cur)
			if tster == nil {
				panic(err)
			}
			tster.Init()
			for true {
				if time.Now().After(endTime) {
					wg.Done()
					tster.Close()
					return
				}
				var start = time.Now().UnixNano()
				runOk := tster.RunTest()
				tr[cur].costTimeTotal += float64(time.Now().UnixNano()-start) / float64(time.Millisecond)
				if runOk {
					tr[cur].successVisitTotal += 1
				} else {
					tr[cur].errorVisitTotal += 1
				}
			}
		}(i)
	}
	wg.Wait()
	_rst := new(RPCStressTest)
	_rst.ExecuteTime = xecuteTim

	for _, tempSaveObj := range tr {
		_rst.successVisitTotal += tempSaveObj.successVisitTotal
		_rst.errorVisitTotal += tempSaveObj.errorVisitTotal
		_rst.costTimeTotal += tempSaveObj.costTimeTotal
	}
	//输出统计信息
	avgCost := float64(_rst.costTimeTotal) / float64(_rst.successVisitTotal+_rst.errorVisitTotal)
	//qps := int64(_rst.successVisitTotal+_rst.errorVisitTotal) / int64(_rst.costTimeTotal) / float64(time.Second) //（成功+失败）/耗时
	qps := (_rst.successVisitTotal + _rst.errorVisitTotal) / int(_rst.ExecuteTime/time.Second)
	error_rate := float64(_rst.errorVisitTotal) / float64(_rst.successVisitTotal+_rst.errorVisitTotal)
	fmt.Printf("\n=========压测结束, 总响应时长：%vms\t平均响应时长：%vms\t平均QPS：%v/s ===========\n", _rst.costTimeTotal, avgCost, qps)
	//fmt.Printf("\n=========每秒请求数：%v \n", (succCall+failCall)/totalTime)
	fmt.Printf("\n=========总请求数 %v, 成功数 %v, 失败数 %v, 失败率 %v \n", _rst.successVisitTotal+_rst.errorVisitTotal, _rst.successVisitTotal, _rst.errorVisitTotal, error_rate)
	fmt.Println()
}
